/****************************************************************************
*
* Copyright (c) 2023  C*Core -   All Rights Reserved
*
* THIS SOFTWARE IS DISTRIBUTED "AS IS, " AND ALL WARRANTIES ARE DISCLAIMED,
* INCLUDING MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* PROJECT     : CCFC2011BC
* DESCRIPTION : CCFC2011BC dspi low level drivers code
* HISTORY     : Initial version.
* @file     spi_lld.c
* @version  1.1
* @date     2023 - 02 - 20
* @brief    Initial version.
*
*****************************************************************************/

#include "spi_lld.h"
#include "siul_lld.h"
#include "IntcInterrupts.h"
#include "led_hw.h"
#include "edma_lld.h"
#include "CCFC2011BC.h"
#include "common.h"
#include "console.h"

/* Some forward declarations.*/
static void spi_serve_rx_dma_irq(uint32_t *p);
static void spi_serve_tx_dma_irq(uint32_t *p);
static void spi_serve_dma_error_irq(uint32_t *p, uint32_t esr);
/*******************************************************************************
 * Variables
 ******************************************************************************/
/* Defines constant value arrays for the baud rate pre - scalar values.*/

/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==   */
/* Driver local definitions.                                                */
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==   */

/* Excluded PUSHR bits.*/
#define DSPI_PUSHR_EXCLUDED_BITS    (PUSHR_CTAS_MASK   |   /*PRQA S 1534*/             \
                                     PUSHR_EOQ         |              \
                                     PUSHR_TXDATA_MASK)

#define DSPI_POPR8_ADDRESS(spip)    (((uint32_t)&(spip)->dspi->POPR.R) + 3U)/*PRQA S 3472*/
#define DSPI_POPR16_ADDRESS(spip)   (((uint32_t)&(spip)->dspi->POPR.R) + 2U)/*PRQA S 3472*/

/* Set of macros dealing with the variable number of DMAs depending on
   the chosen mode.*/
#define spi_lld_setdma(spip, tx1_cfg, tx2_cfg, rx_cfg)                        \
{                                                                             \
    if ((uint8_t)spip->config->dmaType == (uint8_t)SPI_DMA_RX_AND_TX)                  \
    {                                                                         \
      (spip)->tx1_channel = EdmaChannelAllocate(&(tx1_cfg));                  \
      (spip)->tx2_channel = EdmaChannelAllocate(&(tx2_cfg));                  \
      (spip)->rx_channel = EdmaChannelAllocate(&(rx_cfg));                    \
    }                                                                         \
    else                                                                      \
    {                                                                         \
      (spip)->rx_channel = EdmaChannelAllocate(&(rx_cfg));                    \
    }                                                                         \
}
#define spi_lld_resetdma(tx1_cfg, tx2_cfg, rx_cfg)   /*PRQA S 3472*/          \
{                                                        \
    if ((uint8_t)spip->config->dmaType == (uint8_t)SPI_DMA_RX_AND_TX)                  \
    {                                                                         \
        edmaChannelRelease(&(tx1_cfg));                                       \
        edmaChannelRelease(&(tx2_cfg));                                       \
        edmaChannelRelease(&(rx_cfg));                                        \
    }                                                                         \
    else                                                                      \
    {                                                                         \
        edmaChannelRelease(&(rx_cfg));                                        \
    }                                                                         \
}

/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */
/* Driver exported variables.                                                */
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */

/**
 * @brief   SPID1 driver identifier.
 */
SPIDriver SPID1;
/**
 * @brief   SPID2 driver identifier.
 */
SPIDriver SPID2;

#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144) 
/**
 * @brief   SPID3 driver identifier.
 */
SPIDriver SPID3;

#if defined CCFC2011BC_40L5_LQFP144
/**
 * @brief   SPID4 driver identifier.
 */
SPIDriver SPID4;
/**
 * @brief   SPID5 driver identifier.
 */
SPIDriver SPID5;

#endif
#endif

/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */
/* Driver local variables and types.                                         */
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */

/**
 * @brief   DMA configuration for DSPI0 TX1.
 */
static const edma_channel_config_t spi_dspi0_tx1_dma_config = {
  SPI_DSPI0_TX1_DMA_CH_ID,
#if (EDMA_HAS_MUX  == TRUE)
  DSPI0_TX1_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI0_TX1_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI0_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID1/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI0 TX2.
 */
static const edma_channel_config_t spi_dspi0_tx2_dma_config = {
  SPI_DSPI0_TX2_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  0,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI0_TX2_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI0_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID1/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI0 RX.
 */
static const edma_channel_config_t spi_dspi0_rx_dma_config = {
  SPI_DSPI0_RX_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI0_RX_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI0_RX_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI0_DMA_IRQ_PRIO,
  spi_serve_rx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID1/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI1 TX1.
 */
static const edma_channel_config_t spi_dspi1_tx1_dma_config = {
  SPI_DSPI1_TX1_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI1_TX1_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI1_TX1_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI1_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID2/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI1 TX2.
 */
static const edma_channel_config_t spi_dspi1_tx2_dma_config = {
  SPI_DSPI1_TX2_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  0,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI1_TX2_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI1_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID2/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI1 RX.
 */
static const edma_channel_config_t spi_dspi1_rx_dma_config = {
  SPI_DSPI1_RX_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI1_RX_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI1_RX_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI1_DMA_IRQ_PRIO,
  spi_serve_rx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID2/*PRQA S 0310*/
};


#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144) 
/**
 * @brief   DMA configuration for DSPI2 TX1.
 */
static const edma_channel_config_t spi_dspi2_tx1_dma_config = {
  SPI_DSPI2_TX1_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI2_TX1_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI2_TX1_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI2_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID3/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI2 TX2.
 */
static const edma_channel_config_t spi_dspi2_tx2_dma_config = {
  SPI_DSPI2_TX2_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  0,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI2_TX2_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI2_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID3/*PRQA S 0310*/
};
/**
 * @brief   DMA configuration for DSPI2 RX.
 */
static const edma_channel_config_t spi_dspi2_rx_dma_config = {
  SPI_DSPI2_RX_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI2_RX_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI2_RX_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI2_DMA_IRQ_PRIO,
  spi_serve_rx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID3/*PRQA S 0310*/
};

#if defined CCFC2011BC_40L5_LQFP144
/**
 * @brief   DMA configuration for DSPI3 TX1.
 */
static const edma_channel_config_t spi_dspi3_tx1_dma_config = {
  SPI_DSPI3_TX1_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI3_TX1_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI3_TX1_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI3_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID4/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI3 TX2.
 */
static const edma_channel_config_t spi_dspi3_tx2_dma_config = {
  SPI_DSPI3_TX2_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  0,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI3_TX2_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI3_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID4/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI3 RX.
 */
static const edma_channel_config_t spi_dspi3_rx_dma_config = {
  SPI_DSPI3_RX_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI3_RX_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI3_RX_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI3_DMA_IRQ_PRIO,
  spi_serve_rx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID4/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI4 TX1.
 */
static const edma_channel_config_t spi_dspi4_tx1_dma_config = {
  SPI_DSPI4_TX1_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI4_TX1_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI4_TX1_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI4_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID5/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI4 TX2.
 */
static const edma_channel_config_t spi_dspi4_tx2_dma_config = {
  SPI_DSPI4_TX2_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  0,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI4_TX2_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI4_DMA_IRQ_PRIO,
  spi_serve_tx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID5/*PRQA S 0310*/
};

/**
 * @brief   DMA configuration for DSPI4 RX.
 */
static const edma_channel_config_t spi_dspi4_rx_dma_config = {
  SPI_DSPI4_RX_DMA_CH_ID,
#if (EDMA_HAS_MUX == TRUE)
  DSPI4_RX_DMA_DEV_ID,
#if (EDMA_NUM_OF_MUX > 1U)
  DSPI4_RX_DMA_MUX,
#endif /* (EDMA_NUM_OF_MUX greater than 1U) */
#endif /* EDMA_HAS_MUX */
  SPI_DSPI4_DMA_IRQ_PRIO,
  spi_serve_rx_dma_irq, spi_serve_dma_error_irq, (uint32_t *)&SPID5/*PRQA S 0310*/
};

#endif
#endif
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */
/* Driver local functions.                                                   */
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */
/*******************************************************************************
 * @brief      DSPI unit transfer start.
 * @param[in]  const SPIDriver *spip
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Start(const SPIDriver *spip)
{
    spip->dspi->SR.R = 0xFFFFFFFFU;
    spip->dspi->MCR.B.HALT = 0U;
}
/*******************************************************************************
 * @brief      DSPI unit transfer stop.
 * @param[in]  const SPIDriver *spip
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Stop(const SPIDriver *spip)
{
    /* Stops the DSPI */
    spip->dspi->MCR.R |= MCR_HALT;

    /* Waits till the DSPI is in stopped state and the transfer is completed.*/
    while (spip->dspi->SR.B.TXRXS != 0U)
    {
      ;
    }

    /* Clears DSPI queues.*/
    spip->dspi->MCR.R |= MCR_CLR_TXF | MCR_CLR_RXF;
}
/******************************************************************************* 
 * @brief      Prefills the TX FIFO with idle frames.
 * @param[in]  const SPIDriver *spip, pointer to the @p SPIDriver object
 * @param[in,out]   uint32_t np ,pointer to the number of frames to send greater 
 *                  than zero,contains the number of remaining frames on return
 * @retval     None
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Prefill_Txfifo_Idle(SPIDriver *spip, uint32_t *np)
{
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));
    uint32_t frame;
    while (spip->dspi->SR.B.TXCTR < DSPI_FIFO_DEPTH)
    {
        if (--(*np) == 0U) /*PRQA S 3440*/
        {
            spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd | 0xFFFFUL) & ~PUSHR_CONT;
            break;
        }
        spip->dspi->PUSHR.R = cmd | 0x0000FFFFUL;
        /* Emptying the RX FIFO.*/
        while ((spip->rx_cnt > 0U) && (spip->dspi->SR.B.RXCTR > 0U))
        {
          frame = spip->dspi->POPR.R;
          if (spip->rx.rx_ptr != NULL)
          {
                if (spip->dspi->CTAR[0].B.FMSZ < 8U)
                {
                     *spip->rx.rx_ptr8 = (uint8_t)frame;
                      spip->rx.rx_ptr8++;
                 }
                 else
                 {
                     *spip->rx.rx_ptr16 = (uint16_t)frame;
                      spip->rx.rx_ptr16++;
                  }
             }
             spip->rx_cnt--;
             }
          }
}

/*******************************************************************************
 * @brief   Prefills the TX FIFO with idle frames using dma.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in, out] np    pointer to the number of frames to send, must be
 *                      greater than zero, contains the number of remaining
 *                      frames on return
 *
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Prefill_Txfifo_Idle_dma(SPIDriver *spip, uint32_t *np) /*PRQA S 3673, 3219*/
{
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));
    while (spip->dspi->SR.B.TXCTR < DSPI_FIFO_DEPTH)
    {
      if (--(*np) == 0U)/*PRQA S 3440*/
      {
        spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd | 0xFFFFUL) & ~PUSHR_CONT;
        break;
      }
      spip->dspi->PUSHR.R = cmd | 0x0000FFFFUL;
    }
}

/*******************************************************************************
 * @brief   Prefills the TX FIFO using 8 bits frames.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in, out] np    pointer to the number of frames to send, must be
 *                      greater than zero, contains the number of remaining
 *                      frames on return
 * @param[in, out] txpp  pointer to the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Prefill_Txfifo8(SPIDriver *spip, uint32_t *np, uint8_t **txpp)
{
    uint32_t frame;
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));
    while (spip->dspi->SR.B.TXCTR < DSPI_FIFO_DEPTH)
    {
        frame = **txpp;
        (*txpp)++;

        if (--(*np) == 0U)/*PRQA S 3440*/
        {
            spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd | frame) & ~PUSHR_CONT;
            break;
        }
        spip->dspi->PUSHR.R = cmd | frame;

        /* Emptying the RX FIFO.*/
        INTC_CPR_Init((uint8_t)CPR_PRI_15);   /* Set the current priority */
        while ((spip->dspi->SR.B.RXCTR > 0U) && (spip->rx_cnt > 0U))
        {
            frame = spip->dspi->POPR.R;
            if (spip->rx.rx_ptr != NULL)
            {
              *spip->rx.rx_ptr8 = (uint8_t)frame;
              spip->rx.rx_ptr8++;
            }
            spip->rx_cnt--;
        }
        INTC_CPR_Init((uint8_t)CPR_PRI_0);   /* Set the current priority */
    }
}

/*******************************************************************************
 * @brief   Prefills the TX FIFO using 8 bits frames with dma.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in, out] np    pointer to the number of frames to send, must be
 *                      greater than zero, contains the number of remaining
 *                      frames on return
 * @param[in, out] txpp  pointer to the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Prefill_Txfifo8_dma(SPIDriver *spip, /*PRQA S 3673, 3219*/
                                     uint32_t *np,
                                     const uint8_t **txpp)
{
    uint32_t frame;
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));
    while (spip->dspi->SR.B.TXCTR < DSPI_FIFO_DEPTH)
    {
      frame = **txpp;
      (*txpp)++;

      if (--(*np) == 0U)/*PRQA S 3440*/
      {
        spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd | frame) & ~PUSHR_CONT;
        break;
      }
      spip->dspi->PUSHR.R = cmd | frame;
    }
}

/*******************************************************************************
 * @brief   Prefills the TX FIFO using 16 bits frames.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in, out] np    pointer to the number of frames to send, must be
 *                      greater than zero, contains the number of remaining
 *                      frames on return
 * @param[in, out] txpp  pointer to the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Prefill_Txfifo16(SPIDriver *spip,
                                      uint32_t *np,
                                      uint16_t **txpp)
{
    uint32_t frame;
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));
    while (spip->dspi->SR.B.TXCTR < DSPI_FIFO_DEPTH)
    {
      frame = **txpp;
      (*txpp)++;

      if (--(*np) == 0U)/*PRQA S 3440*/
      {
        spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd | frame) & ~PUSHR_CONT;
        break;
      }
      spip->dspi->PUSHR.R = cmd | frame;

      INTC_CPR_Init((uint8_t)CPR_PRI_15);   /* Set the current priority */
      while ((spip->rx_cnt > 0U) && (spip->dspi->SR.B.RXCTR > 0U)) /* Emptying the RX FIFO.*/
      {
        frame = spip->dspi->POPR.R;
        if (spip->rx.rx_ptr != NULL)
        {
          *(spip->rx.rx_ptr16) = (uint16_t)frame;
          spip->rx.rx_ptr16++;
        }
        spip->rx_cnt--;
      }
      INTC_CPR_Init((uint8_t)CPR_PRI_0);   /* Set the current priority */
    }
}

/*******************************************************************************
 * @brief   Prefills the TX FIFO using 16 bits frames with dma.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in, out] np    pointer to the number of frames to send, must be
 *                      greater than zero, contains the number of remaining
 *                      frames on return
 * @param[in, out] txpp  pointer to the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Dspi_Prefill_Txfifo16_dma(SPIDriver *spip, /*PRQA S 3673, 3219*/
                                      uint32_t *np,
                                      const uint16_t **txpp)
{
    uint32_t frame;
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));
    while (spip->dspi->SR.B.TXCTR < DSPI_FIFO_DEPTH)
    {
      frame = **txpp;
      (*txpp)++;

      if (--(*np) == 0U) /*PRQA S 3440*/
      {
        spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd | frame) & ~PUSHR_CONT;
        break;
      }
      spip->dspi->PUSHR.R = cmd | frame;
    }
}

/*******************************************************************************
 * @brief   Starts reception without DMA ignoring the received data.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Rx_Ignore(SPIDriver *spip, uint32_t n)
{
    /* Setting up the fields required for operation continuation.*/
    spip->rx.rx_ptr = NULL;
    spip->rx_cnt = n;

    spip->dspi->RSER.B.RFDFRE = 1u;
}
/*******************************************************************************
 * @brief   Starts reception using DMA ignoring the received data with dma.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Rx_Ignore_dma(const SPIDriver *spip, uint32_t n)
{
    static uint32_t const datasink[8];
    uint32_t const *pdatasink = datasink;

    EdmaChannelSetup(spip->rx_channel,            /* channel.                 */ /* PRQA S 0662, 0310, 0312,2985, 3469*/
                        DSPI_POPR8_ADDRESS(spip),    /* src.                     */
                        pdatasink,                   /* dst.                     */
                        0,                           /* soff, do not advance.    */
                        0,                           /* doff, do not advance.    */
                        0,                           /* ssize, 8 bits transfers. */
                        0,                           /* dsize, 8 bits transfers. */
                        1,                           /* nbytes, always one.      */
                        n,                           /* iter.                    */
                        0,                           /* slast.                   */
                        0,                           /* dlast.                   */
                        EDMA_TCD_MODE_DREQ | EDMA_TCD_MODE_INT_END);     /* mode.*/

    /* Starting RX DMA channel.*/
    EdmaChannelStart(spip->rx_channel); /*PRQA S 3469*/

    /* Only when Slave Transmit */
    if (spip->dspi->MCR.B.MSTR == 0UL)
    {
      spip->dspi->RSER.B.TFFFRE = 1;
    }
}

/*******************************************************************************
 * @brief   Starts reception using DMA for frames up to 8 bits.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[out] rxbuf    the pointer to the receive buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Rx8(SPIDriver *spip, uint32_t n, uint8_t *rxbuf)
{
    /* Setting up the fields required for operation continuation.*/
    spip->rx.rx_ptr8 = rxbuf;
    spip->rx_cnt  = n;
    spip->dspi->RSER.B.RFDFRE = 1;
}
/*******************************************************************************
 * @brief   Starts reception using DMA for frames up to 8 bits with dma.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[out] rxbuf    the pointer to the receive buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Rx8_dma(const SPIDriver *spip, uint32_t n, const uint8_t *rxbuf)
{
    EdmaChannelSetup(spip->rx_channel,            /* channel.                 */   /* PRQA S 0662, 0310,0312, 2985, 3469 */
                        DSPI_POPR8_ADDRESS(spip),    /* src.                     */
                        rxbuf,                       /* dst.                     */
                        0,                           /* soff, do not advance.    */
                        1,                           /* doff, advance by one.    */
                        0,                           /* ssize, 8 bits transfers. */
                        0,                           /* dsize, 8 bits transfers. */
                        1,                           /* nbytes, always one.      */
                        n,                           /* iter.                    */
                        0,                           /* slast.                   */
                        0,                           /* dlast.                   */
                        EDMA_TCD_MODE_DREQ|EDMA_TCD_MODE_INT_END);     /* mode.*/

    /* Starting RX DMA channel.*/
    EdmaChannelStart(spip->rx_channel); /*PRQA S 3469*/
}

/*******************************************************************************
 * @brief   Starts reception without DMA for frames up to 16 bits.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[out] rxbuf    the pointer to the receive buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Rx16(SPIDriver *spip, uint32_t n, uint16_t *rxbuf)
{
    /* Setting up the fields required for operation continuation.*/
    spip->rx.rx_ptr16 = rxbuf;
    spip->rx_cnt   = n;

    spip->dspi->RSER.B.RFDFRE = 1u;
}
/*******************************************************************************
 * @brief   Starts reception using DMA for frames up to 16 bits with dma.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[out] rxbuf    the pointer to the receive buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Rx16_dma(const SPIDriver *spip, uint32_t n, const uint16_t *rxbuf)
{
    EdmaChannelSetup(spip->rx_channel,            /* channel.                 */ /* PRQA S 0310,0312, 3469, 0662 */
                    DSPI_POPR16_ADDRESS(spip),   /* src.                     */
                    rxbuf,                       /* dst.                     */
                    0,                           /* soff, do not advance.    */
                    2,                           /* doff, advance by two.    */
                    1,                           /* ssize, 16 bits transfers.*/
                    1,                           /* dsize, 16 bits transfers.*/
                    2,                           /* nbytes, always two.      */
                    n,                           /* iter.                    */
                    0,                           /* slast, no source adjust. */
                    0,                           /* dlast.                   */
                    EDMA_TCD_MODE_DREQ | EDMA_TCD_MODE_INT_END); /* mode.    */

    /* Starting RX DMA channel.*/
    EdmaChannelStart(spip->rx_channel); /*PRQA S 3469*/
}
/*******************************************************************************
 * @brief   Starts transmission without DMA for frames up to 8 bits.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Tx_Ignore(SPIDriver *spip, uint32_t n)
{
    /* Preloading the TX FIFO with as much frames as possible.*/
    Spi_Dspi_Prefill_Txfifo_Idle(spip, &n); /*PRQA S 1339*/

    /* This is the case where the whole operation can be satisfied using the
      preloading alone.*/
    if (n == 0U)
    {
      return;
    }

    /* Setting up the fields required for operation continuation.*/
    spip->tx.tx_ptr = NULL;
    spip->tx_cnt = n;

    /* Enabling the TFFF interrupt source for transfer continuation.*/
    spip->dspi->RSER.B.TFFFRE = 1;
}

/*******************************************************************************
 * @brief   Starts transmission using DMA for frames up to 8 bits with dma.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Tx_Ignore_dma(SPIDriver *spip, uint32_t n)
{
    /* Special case when the data to be transmitted can entirely fit into the
      TX FIFO, in this case the TX DMAs are not activated.*/
    if (n <= DSPI_FIFO_DEPTH)
    {
      Spi_Dspi_Prefill_Txfifo_Idle(spip, &n); /*PRQA S 1339*/
      return;
    }

    /* Preparing the TX intermediate buffer with the fixed part.*/
    spip->tx_cmd = (0xFFFFU | ((((uint32_t)(spip->config->continuousPCS)) << 31U) &
         (~(((uint32_t)(spip->config->continuousPCS)) << 27U)))) |
        (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16U);
    /* The first frame is pushed by the CPU, then the DMA is activated to
      send the following frames. This should reduce latency on the operation
      start.*/
    spip->dspi->PUSHR.R = spip->tx_cmd;
    spip->tx_last = spip->tx_cmd;

    /* Setting up TX1 DMA TCD parameters for 32 bits transfers.*/
    EdmaChannelSetup(spip->tx1_channel,           /* channel.                 */ /* PRQA S 0662, 0310,0312, 2985, 3469 */
                    &spip->tx_cmd,               /* src.                     */
                    &spip->dspi->PUSHR.R,        /* dst.                     */
                    0,                           /* soff, do not advance.    */
                    0,                           /* doff, do not advance.    */
                    2,                           /* ssize, 32 bits transfers.*/
                    2,                           /* dsize, 32 bits transfers.*/
                    4,                           /* nbytes, always four.     */
                    n - 2U,                      /* iter.                    */
                    0,                           /* slast, no source adjust. */
                    0,                           /* dlast, no dest.adjust.   */
                    EDMA_TCD_MODE_DREQ | EDMA_TCD_MODE_INT_END); /* mode.    */

    /* Starting TX1 DMA channel.*/
    EdmaChannelStart(spip->tx1_channel); /*PRQA S 3469*/
}
/*******************************************************************************
 * @brief   Starts transmission without DMA for frames up to 8 bits.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[in] txbuf     the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Tx8(SPIDriver *spip, uint32_t n, uint8_t *txbuf)
{
    /* Enabling the EOQF interrupt source for transfer complete.
    * This interrupt is not valid in slave mode.
    */
    if (spip->dspi->MCR.B.MSTR == 1UL)
    {
        spip->dspi->RSER.B.EOQFRE = 1;
    }

    /* Preloading the TX FIFO with as much frames as possible.*/
    Spi_Dspi_Prefill_Txfifo8(spip, &n, &txbuf); /*PRQA S 1339*/

    /* This is the case where the whole operation can be satisfied using the
      preloading alone.*/
    if (n == 0U)
    {
      return;
    }

    /* Setting up the fields required for operation continuation.*/
    spip->tx.tx_ptr8 = txbuf;
    spip->tx_cnt = n;

    /* Enabling the TFFF interrupt source for transfer continuation.*/
    spip->dspi->RSER.B.TFFFRE = 1;
}
/*******************************************************************************
 * @brief   Starts transmission using DMA for frames up to 8 bits.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[in] txbuf     the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Tx8_dma(SPIDriver *spip, uint32_t n,  uint8_t *txbuf)
{
  uint8_t last_frame;
  const uint8_t *src, *dst;

  /* Special case when the data to be transmitted can entirely fit into the
     TX FIFO, in this case the TX DMAs are not activated.*/
  if (n <= DSPI_FIFO_DEPTH)
  {
    Spi_Dspi_Prefill_Txfifo8(spip, &n, &txbuf); /*PRQA S 1339*/
    return;
  }

  /* Preparing the TX intermediate buffer with the fixed part.*/
  /* The first frame is pushed immediately, then the DMA is activated to
     send the following frames. This should reduce latency on the operation
     start.*/
  spip->tx_cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
                  (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
                   (((uint32_t)(((uint32_t)1) << (spip->config->whichPCS))) << 16)) | ((uint32_t)(*txbuf));
  /* The last frame is a special case, will be pushed by the TX FIFO drain
     interrupt handler or the DMA final callback.*/
  last_frame = txbuf[n - 1U];
  spip->tx_last = (uint32_t)last_frame;
  /* At least two frames left, the DMA is enabled in order to handle the
     long transfer, note that the final frame is not pushed by the DMA.*/
  /* Setting up TX1 DMA TCD parameters for 8 bits transfers.*/
  src = txbuf + 1;
  dst = ((const uint8_t *)&spip->tx_cmd) + 3;
  EdmaChannelSetupLinked(spip->tx1_channel,           /* channel.    */     /*PRQA S 0662, 0310,0312, 2985, 3469 */
                            spip->tx2_channel,           /* linkch.                  */
                            &spip->tx_cmd,               /* src.                     */
                            &spip->dspi->PUSHR.R,        /* dst.                     */
                            0,                           /* soff, do not advance.    */
                            0,                           /* doff, do not advance.    */
                            2,                           /* ssize, 32 bits transfers.*/
                            2,                           /* dsize, 32 bits transfers.*/
                            4,                           /* nbytes, always four.     */
                            n - 1U,                      /* iter.                    */
                            0,                           /* slast, no source adjust. */
                            0,                           /* dlast, no dest.adjust.   */
                            EDMA_TCD_MODE_DREQ| EDMA_TCD_MODE_INT_END); /* mode.    */
  /* Setting up TX2 DMA TCD parameters for 32 bits transfers.*/
  EdmaChannelSetup(spip->tx2_channel,  /* channel.       */         /*PRQA S 0662, 0310,0312, 2985, 3469 */
                    src,                         /* src.                     */
                    dst,                         /* dst.                     */
                    1,                           /* soff, advance by 1.      */
                    0,                           /* doff, do not advance.    */
                    0,                           /* ssize, 8 bits transfers. */
                    0,                           /* dsize, 8 bits transfers. */
                    1,                           /* nbytes, always one.      */
                    n - 1U,                      /* iter.                    */
                    0,                           /* slast, no source adjust. */
                    0,                           /* dlast, no dest.adjust.   */
                    EDMA_TCD_MODE_DREQ);         /* mode.                    */
  /* Starting TX DMA channels.*/
  EdmaChannelStart(spip->tx2_channel); /*PRQA S 3469*/
  EdmaChannelStart(spip->tx1_channel); /*PRQA S 3469*/
}
/*******************************************************************************
 * @brief   Starts transmission without DMA for frames up to 16 bits.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[in] txbuf     the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Tx16(SPIDriver *spip, uint32_t n, uint16_t *txbuf)
{
    /* Enabling the EOQF interrupt source for transfer complete.
    * This interrupt is not valid in slave mode.
    */
    if (spip->dspi->MCR.B.MSTR == 1UL)
    {
       spip->dspi->RSER.B.EOQFRE = 1;
    }

    /* Preloading the TX FIFO with as much frames as possible.*/
    Spi_Dspi_Prefill_Txfifo16(spip, &n, &txbuf); /*PRQA S 1339*/

    /* This is the case where the whole operation can be satisfied using the
      preloading alone.*/
    if (n == 0U)
    {
      return;
    }

    /* Setting up the fields required for operation continuation.*/
    spip->tx.tx_ptr16 = txbuf;
    spip->tx_cnt = n;

    /* Enabling the TFFF interrupt source for transfer continuation.*/
    spip->dspi->RSER.B.TFFFRE = 1;
}

/*******************************************************************************
 * @brief   Starts transmission using DMA for frames up to 16 bits.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[in] txbuf     the pointer to the transmit buffer
 *
 * @notapi
 *******************************************************************************/
static void Spi_Start_Tx16_dma(SPIDriver *spip, uint32_t n, uint16_t *txbuf)
{
  uint16_t last_frame;
  const uint16_t *src;
  const uint8_t  *dst;

  /* Special case when the data to be transmitted can entirely fit into the
     TX FIFO, in this case the TX DMAs are not activated.*/
  if (n <= DSPI_FIFO_DEPTH)
  {
    Spi_Dspi_Prefill_Txfifo16(spip, &n, &txbuf); /*PRQA S 1339*/
    return;
  }

  /* Preparing the TX intermediate buffer with the fixed part.*/
  /* The first frame is pushed immediately, then the DMA is activated to
     send the following frames. This should reduce latency on the operation
     start.*/
  spip->tx_cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
                  (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
                  (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16)) | ((uint32_t)(*txbuf));
  /* The last frame is a special case, will be pushed by the TX FIFO drain
     interrupt handler or the DMA final callback.*/
  last_frame = txbuf[n - 1U];
  spip->tx_last = (uint32_t)last_frame;
  /* At least two frames left, the DMA is enabled in order to handle the
     long transfer, note that the final frame is not pushed by the DMA.*/
  /* Setting up TX1 DMA TCD parameters for 8 bits transfers.*/
  src = txbuf + 1U;
  dst = ((const uint8_t *)&spip->tx_cmd) + 2U;
  EdmaChannelSetupLinked(spip->tx1_channel,           /* channel.                 */   /*PRQA S 0662, 0310, 0312,2985, 3469*/
                        spip->tx2_channel,           /* linkch.                  */
                        &spip->tx_cmd,               /* src.                     */
                        &spip->dspi->PUSHR.R,        /* dst.                     */
                        0,                           /* soff, do not advance.    */
                        0,                           /* doff, do not advance.    */
                        2,                           /* ssize, 32 bits transfers.*/
                        2,                           /* dsize, 32 bits transfers.*/
                        4,                           /* nbytes, always four.     */
                        n - 1U,                      /* iter.                    */
                        0,                           /* slast, no source adjust. */
                        0,                           /* dlast, no dest.adjust.   */
                        EDMA_TCD_MODE_DREQ| EDMA_TCD_MODE_INT_END); /* mode.    */
  /* Setting up TX2 DMA TCD parameters for 32 bits transfers.*/
  EdmaChannelSetup(spip->tx2_channel,           /* channel.                 */  /*PRQA S 0662, 0310,0312, 2985, 3469*/
                    src,                         /* src.                     */
                    dst,                         /* dst.                     */
                    2,                           /* soff, advance by 1.      */
                    0,                           /* doff, do not advance.    */
                    1,                           /* ssize, 8 bits transfers. */
                    1,                           /* dsize, 8 bits transfers. */
                    2,                           /* nbytes, always two.      */
                    n - 1U,                      /* iter.                    */
                    0,                           /* slast, no source adjust. */
                    0,                           /* dlast, no dest.adjust.   */
                    EDMA_TCD_MODE_DREQ);         /* mode.                    */

  /* Starting TX DMA channels.*/
  EdmaChannelStart(spip->tx2_channel); /*PRQA S 3469*/
  EdmaChannelStart(spip->tx1_channel); /*PRQA S 3469*/
}
/*******************************************************************************
 * @brief   Shared RX DMA events service routine.
 *
 * @param[in] channel   the channel number
 * @param[in] p         parameter for the registered function
 *
 * @notapi
 *******************************************************************************/
static void spi_serve_rx_dma_irq(uint32_t *p)
{
    /*Casting of void pointer needful for using the same DMA driver
      in different drivers. */
    SPIDriver *spip = (SPIDriver *)p; /*PRQA S 0310*/

    /* Clearing RX channel state.*/
    EdmaChannelStop(spip->rx_channel); /*PRQA S 3469*/
    /* Stops the transfer.*/
    Spi_Dspi_Stop(spip);

    /* Call the related callback.*/
    if (spip->config->callback != NULL)
    {
        spip->config->callback(spip);
    }

    SPI_TXRX_DONE(spip);
}

/*******************************************************************************
 * @brief   Shared TX1/TX2 DMA events service routine.
 *
 * @param[in] channel   the channel number
 * @param[in] p         parameter for the registered function
 *
 * @notapi
 *******************************************************************************/
static void spi_serve_tx_dma_irq(uint32_t *p)/*PRQA S 3673*/
{
    /*Casting of void pointer needful for using the same DMA driver
      in different drivers. */
    SPIDriver *spip = (SPIDriver *)p; /*PRQA S 3678, 0310*/
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31U) &
         (~(((uint32_t)(spip->config->continuousPCS)) << 27U)))) |
        (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16U);

    /* Clearing TX channels state.*/
    EdmaChannelStop(spip->tx1_channel); /*PRQA S 3469*/
    EdmaChannelStop(spip->tx2_channel); /*PRQA S 3469*/

    /* If the TX FIFO is full then the push of the last frame is delegated to
      an interrupt handler else it is performed immediately. Both conditions
      can be true depending on the SPI speed and ISR latency.*/
    if (spip->dspi->SR.B.TFFF != 0U)
    {
      spip->dspi->PUSHR.R = (cmd | spip->tx_last | PUSHR_EOQ) & ~PUSHR_CONT;
    }
    else
    {
      spip->dspi->RSER.B.TFFFDIRS = 0U;
      LED_Set(LED2, LED_ON);
    }
}

/*******************************************************************************
 * @brief   Shared ISR for DMA error events.
 *
 * @param[in] channel   the channel number
 * @param[in] p         parameter for the registered function
 * @param[in] esr       content of the ESR register
 *
 * @notapi
 *******************************************************************************/
static void spi_serve_dma_error_irq(uint32_t *p, uint32_t esr)/*PRQA S 3673*/
{
    /*Casting of void pointer needful for using the same DMA driver
      in different drivers. */
    SPIDriver const *spip = (SPIDriver *)p; /*PRQA S 0310*/

    (void)esr; /* PRQA S 3119*/

    /* Stops the transfer.*/
    Spi_Dspi_Stop(spip);

  #if SPI_DMA_MODE == SPI_DMA_RX_AND_TX
    /* Clearing TX channels state.*/
    EdmaChannelStop(spip->tx1_channel); /*PRQA S 3469*/
    EdmaChannelStop(spip->tx2_channel); /*PRQA S 3469*/
  #endif
    /* Clearing RX channel state.*/
    EdmaChannelStop(spip->rx_channel); /*PRQA S 3469*/

    SPI_DMA_ERROR_HOOK(spip);
}
/*******************************************************************************
 * @brief   Shared ISR for EOQF DSPI events.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 *
 * @notapi
 *******************************************************************************/
static void spi_serve_dspi_eoqf(SPIDriver *spip)
{
    /* Emptying the RX FIFO.*/
      while ((spip->dspi->SR.B.RXCTR > 0U) && (spip->rx_cnt > 0U))
      {
      uint32_t frame = spip->dspi->POPR.R;

      if (spip->rx.rx_ptr != NULL)
      {
        if (spip->dspi->CTAR[0].B.FMSZ < 8U)
        {
          *spip->rx.rx_ptr8 = (uint8_t)frame;
           spip->rx.rx_ptr8++;
        }
        else
        {
          *spip->rx.rx_ptr16 = (uint16_t)frame;
          spip->rx.rx_ptr8++;
        }
      }
      spip->rx_cnt--;
    }

    /* Interrupt served.*/
    spip->dspi->SR.R = RSER_EOQF_RE;

    /* Done with transfer, disable interrupt */
    spip->dspi->RSER.B.EOQFRE = 0;

    if (spip->rx_cnt == 0U)
    {
      /* Stops the transfer.*/
      Spi_Dspi_Stop(spip);

      /* Call the related callback.*/
      if (spip->config->callback != NULL)
      {
        spip->config->callback(spip);
      }

      SPI_TXRX_DONE(spip);
    }
}

/*******************************************************************************
 * @brief   Shared ISR for RFDF DSPI events.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 *
 * @notapi
 *******************************************************************************/
static void Spi_Serve_Dspi_Rfdf(SPIDriver *spip)
{
    uint32_t cs0;/* valid only in slave mode */
    while ((spip->dspi->SR.B.RXCTR > 0U) && (spip->rx_cnt > 0U))  /* Emptying the RX FIFO.*/
    {
      uint32_t frame = spip->dspi->POPR.R ;
      if (spip->rx.rx_ptr != NULL)
      {
        if (spip->dspi->CTAR[0].B.FMSZ < 8U)
        {
          *spip->rx.rx_ptr8 = (uint8_t)frame;
           spip->rx.rx_ptr8++;
        }
        else
        {
          *spip->rx.rx_ptr16 = (uint16_t)frame;
           spip->rx.rx_ptr8++;
        }
      }
      spip->rx_cnt--;
    }
    /* Interrupt served.*/
    spip->dspi->SR.R = RSER_RFDF_RE;

    if (spip->dspi->MCR.B.MSTR == 1U)
    {
    /* this DSPI is in master mode */
    cs0 = 0U;
    }
    else
    {
    /* this DSPI is in slave mode, actually assuming CS0(DSPI0_CS0 PA[0]) is active low */
      cs0 = SIUL_GPIO_InputRead((0*16) + 15);
    }
    if ((cs0 != 0U) || (spip->rx_cnt == 0U))
    {
    /* Done with transfer, disable interrupt */
    spip->dspi->RSER.B.RFDFRE = 0u;

    /* Stops the transfer.*/
      Spi_Dspi_Stop(spip);

      /* Call the related callback.*/
      if (spip->config->callback != NULL)
      {
          spip->config->callback(spip);
      }

      SPI_TXRX_DONE(spip);
    }
}
/*******************************************************************************
 * @brief   Shared ISR for TFFF DSPI events.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 *
 * @notapi
 *******************************************************************************/
static void Spi_Serve_Dspi_Tfff(SPIDriver *spip)
{
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31U) &
         (~(((uint32_t)(spip->config->continuousPCS)) << 27U)))) |
        (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16U);

    if ((uint8_t)spip->config->dmaType != SPI_DMA_RX_AND_TX)/* PRQA S 1863*/
    {
        if (spip->tx_cnt > 0u)
        {
                /* Filling the TX FIFO.*/
                if (spip->tx.tx_ptr == NULL)
                {
                    Spi_Dspi_Prefill_Txfifo_Idle(spip, &spip->tx_cnt);
                  }
                else
                {
                    if (spip->dspi->CTAR[0].B.FMSZ < 8u)
                    {
                      Spi_Dspi_Prefill_Txfifo8(spip, (uint32_t *)&spip->tx_cnt, &spip->tx.tx_ptr8);
                    }
                    else
                    {
                      Spi_Dspi_Prefill_Txfifo16(spip, (uint32_t *)&spip->tx_cnt, &spip->tx.tx_ptr16);
                    }
                  }
        }
        /* Interrupt served.*/
        spip->dspi->SR.R = RSER_TFFF_RE;

        /* Done with transfer, disable interrupt */
        if (spip->tx_cnt == 0U)
        {
        spip->dspi->RSER.B.TFFFRE = 0u;
        }
    }
    else
    {
      /* Interrupt served and back to DMA mode.*/
      spip->dspi->RSER.B.TFFFDIRS = 1u;
      spip->dspi->SR.B.TFFF = 1u;

      /* Pushing last frame.*/
      spip->dspi->PUSHR.R = (cmd| spip->tx_last | PUSHR_EOQ) & ~PUSHR_CONT;

      while (spip->dspi->SR.B.TCF != 1u)
      {
      }
      spip->dspi->SR.B.TCF = 1u;

      LED_Set(LED3, LED_ON);
    }
}
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */
/* Driver interrupt handlers.                                                */
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */
/**
 * @brief   DSPI0 EOQF interrupt handler.
 *
 * @isr
 */
#if!defined(DSPI0_RFDF_HANDLER)
#error "DSPI0_RFDF_HANDLER not defined"
#endif
/**
 * @brief   DSPI0 RFDF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI0_RFDF_HANDLER)/*PRQA S 1505*/
{
    IRQ_PROLOGUE();

    Spi_Serve_Dspi_Rfdf(&SPID1);

  IRQ_EPILOGUE();
}

#if!defined(DSPI0_EOQF_HANDLER)
#error "DSPI0_EOQF_HANDLER not defined"
#endif
/**
 * @brief   DSPI0 EOQF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI0_EOQF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  spi_serve_dspi_eoqf(&SPID1);

  IRQ_EPILOGUE();
}

#if!defined(DSPI1_RFDF_HANDLER)
#error "DSPI1_RFDF_HANDLER not defined"
#endif
/**
 * @brief   DSPI1 RFDF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI1_RFDF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Rfdf(&SPID2);

  IRQ_EPILOGUE();
}

#if!defined(DSPI1_EOQF_HANDLER)
#error "DSPI1_EOQF_HANDLER not defined"
#endif
/**
 * @brief   DSPI1 EOQF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI1_EOQF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  spi_serve_dspi_eoqf(&SPID2);

  IRQ_EPILOGUE();
}

#if!defined(DSPI2_RFDF_HANDLER)
#error "DSPI2_RFDF_HANDLER not defined"
#endif
/**
 * @brief   DSPI2 RFDF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI2_RFDF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Rfdf(&SPID3);

  IRQ_EPILOGUE();
}

#if!defined(DSPI2_EOQF_HANDLER)
#error "DSPI2_EOQF_HANDLER not defined"
#endif
/**
 * @brief   DSPI2 EOQF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI2_EOQF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  spi_serve_dspi_eoqf(&SPID3);

  IRQ_EPILOGUE();
}

#if!defined(DSPI3_RFDF_HANDLER)
#error "DSPI3_RFDF_HANDLER not defined"
#endif
/**
 * @brief   DSPI3 RFDF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI3_RFDF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Rfdf(&SPID4);

  IRQ_EPILOGUE();
}

#if!defined(DSPI3_EOQF_HANDLER)
#error "DSPI3_EOQF_HANDLER not defined"
#endif
/**
 * @brief   DSPI3 EOQF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI3_EOQF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  spi_serve_dspi_eoqf(&SPID4);

  IRQ_EPILOGUE();
}

#if!defined(DSPI4_RFDF_HANDLER)
#error "DSPI4_RFDF_HANDLER not defined"
#endif
/**
 * @brief   DSPI4 RFDF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI4_RFDF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Rfdf(&SPID5);

  IRQ_EPILOGUE();
}

#if!defined(DSPI4_EOQF_HANDLER)
#error "DSPI4_EOQF_HANDLER not defined"
#endif
/**
 * @brief   DSPI4 EOQF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI4_EOQF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  spi_serve_dspi_eoqf(&SPID5);

  IRQ_EPILOGUE();
}


#if!defined(DSPI0_TFFF_HANDLER)
#error "DSPI0_TFFF_HANDLER not defined"
#endif
/**
 * @brief   DSPI0 TFFF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI0_TFFF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Tfff(&SPID1);

  IRQ_EPILOGUE();
}

#if!defined(DSPI1_TFFF_HANDLER)
#error "DSPI1_TFFF_HANDLER not defined"
#endif
/**
 * @brief   DSPI1 TFFF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI1_TFFF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Tfff(&SPID2);

  IRQ_EPILOGUE();
}

#if!defined(DSPI2_TFFF_HANDLER)
#error "DSPI2_TFFF_HANDLER not defined"
#endif
/**
 * @brief   DSPI2 TFFF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI2_TFFF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Tfff(&SPID3);

  IRQ_EPILOGUE();
}

#if!defined(DSPI3_TFFF_HANDLER)
#error "DSPI3_TFFF_HANDLER not defined"
#endif
/**
 * @brief   DSPI3 TFFF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI3_TFFF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Tfff(&SPID4);

  IRQ_EPILOGUE();
}

#if!defined(DSPI4_TFFF_HANDLER)
#error "DSPI4_TFFF_HANDLER not defined"
#endif
/**
 * @brief   DSPI4 TFFF interrupt handler.
 *
 * @isr
 */
IRQ_HANDLER(DSPI4_TFFF_HANDLER)/*PRQA S 1505*/
{
  IRQ_PROLOGUE();

  Spi_Serve_Dspi_Tfff(&SPID5);

  IRQ_EPILOGUE();
}

/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  =*/
/* Driver exported functions.                                                */
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */

/*******************************************************************************
 * @brief      abs_dif
 * @param[in]  uint32_t a, uint32_t b
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static uint32_t abs_dif(uint32_t a, uint32_t b)
{
    if (a > b)
    {
        return(a - b);
    }
    else
    {
        return(b - a);
    }
}

void spi_set_disable_fifo(const SPIDriver *spip)
{
    spip->dspi->MCR.B.MDIS = 0u;
    spip->dspi->MCR.B.DIS_TXF = 1u;
    spip->dspi->MCR.B.DIS_RXF = 1u;
    spip->dspi->MCR.B.MDIS = 1u;
}
/*******************************************************************************
 * @brief   Install INT functions for  the SPI peripheral.
 *
 * @param[in] Dspix      Index of specific SPIDriver object
 *
 * @param[in] spi_mode   configure the SPIDriver object master or slave
 * @api
 *******************************************************************************/
void SPI_LLD_Gpio_Init(uint8_t dspix, uint8_t spi_mode)/*PRQA S 1505*/
{
    if (dspix == (uint8_t)DSPI0)/*DSPI_0*/
     {
         SPID1.dspi = &DSPI_0;
         if (spi_mode == (uint8_t)SPI_MASTER)
         {
          SIU.PCR[12].R = 0x0104;         /* assign port PA[12] pad to Alt Func 1 input  SIN*/
          SIU.PCR[13].R = 0x0604;         /* assign port PA[13] pad to Alt Func 1 output SOUT*/
          SIU.PCR[14].R = 0x0604;         /* assign port PA[14] pad to Alt Func 1 output SCK*/
          SIU.PCR[15].R = 0x0607;         /* assign port PA[15] pad to Alt Func 1 output  CS0 */
         }
         else
         {
          SIU.PCR[12].R = 0x0104;         /* assign port PA[12] pad to Alt Func 1  input SIN*/
          SIU.PCR[13].R = 0x0604;         /* assign port PA[13] pad to Alt Func 1 output SOUT*/
          SIU.PCR[14].R = 0x0504;         /* assign port PA[14] pad to Alt Func 1 input SCK*/
          SIU.PSMI[5].R = 0;
          SIU.PCR[15].R = 0x0507;         /* assign port PA[15] pad to Alt Func 1 input CS0 */
          SIU.PSMI[6].R = 1;
         }
     }
     if (dspix == (uint8_t)DSPI1)/*DSPI_1*/
     {
         SPID2.dspi = &DSPI_1;
         if (spi_mode == (uint8_t)SPI_MASTER)
         {
          SIU.PCR[34].R = 0x0604;         /* assign port PC[2] pad to Alt Func 1 output SCK*/
          SIU.PCR[35].R = 0x0607;         /* assign port PC[3] pad to Alt Func 1 input  CS0 */
          SIU.PCR[36].R = 0x0104;         /* assign port PC[4] pad to Alt Func 1 input  SIN*/
          SIU.PCR[37].R = 0x0604;         /* assign port PC[5] pad to Alt Func 1 output SOUT*/
         }
          else
          {
          SIU.PCR[34].R = 0x0504;         /* assign port PC[2] pad to Alt Func 1 input SCK*/
          SIU.PCR[35].R = 0x0507;         /* assign port PC[3] pad to Alt Func 1 input CS0 */
          SIU.PCR[36].R = 0x0104;         /* assign port PC[4] pad to Alt Func 1  input SIN*/
          SIU.PCR[37].R = 0x0604;         /* assign port PC[5] pad to Alt Func 1 output SOUT*/
          }
     }
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144)
     if (dspix == (uint8_t)DSPI2)/*DSPI_2*/
     {
         SPID3.dspi = &DSPI_2;
         if (spi_mode == (uint8_t)SPI_MASTER)
         {
          SIU.PCR[44].R = 0x0104;         /* assign port PC[12] pad to Alt Func 2 input  SIN*/
          SIU.PCR[45].R = 0x0a04;         /* assign port PC[13] pad to Alt Func 2 output SOUT*/
          SIU.PCR[46].R = 0x0a04;         /* assign port PC[14] pad to Alt Func 2 output SCK*/
          SIU.PCR[47].R = 0x0a07;         /* assign port PC[15] pad to Alt Func 2 input  CS0 */
         }
         else
         {
          SIU.PCR[44].R = 0x0104;         /* assign port PC[12] pad to Alt Func 2  input SIN*/
          SIU.PCR[45].R = 0x0a04;         /* assign port PC[13] pad to Alt Func 2 output SOUT*/
          SIU.PCR[46].R = 0x0904;         /* assign port PC[14] pad to Alt Func 2 input SCK*/
          SIU.PCR[47].R = 0x0907;         /* assign port PC[15] pad to Alt Func 2 input CS0 */
         }
     }
#if defined CCFC2011BC_40L5_LQFP144
     if (dspix == (uint8_t)DSPI3)/*DSPI_3*/
     {
         SPID4.dspi = &DSPI_3;
         if (spi_mode == (uint8_t)SPI_MASTER)
         {
          SIU.PCR[98].R = 0x0a04;         /* assign port PG[2] pad to Alt Func 2 output SOUT*/
          SIU.PCR[99].R = 0x0a07;         /* assign port PG[3] pad to Alt Func 2 input  CS0 */
          SIU.PCR[100].R = 0x0a04;         /* assign port PG[4] pad to Alt Func 2 output SCK*/
          SIU.PCR[101].R = 0x0104;         /* assign port PG[5] pad to Alt Func 2 input  SIN*/
         }
         else
         {
          SIU.PCR[98].R = 0x0a04;         /* assign port PG[2] pad to Alt Func 2 output SOUT*/
          SIU.PCR[99].R = 0x0907;         /* assign port PG[3] pad to Alt Func 2 input CS0 */
          SIU.PCR[100].R = 0x0904;         /* assign port PG[4] pad to Alt Func 2 input SCK*/
          SIU.PCR[101].R = 0x0104;         /* assign port PG[5] pad to Alt Func 2  input SIN*/
         }
     }
     if (dspix == (uint8_t)DSPI4)/*DSPI_4*/
     {
         SPID5.dspi = &DSPI_4;
         if (spi_mode == (uint8_t)SPI_MASTER)
         {
          SIU.PCR[106].R = 0x0104;         /* assign port PG[10] pad to Alt Func 2 input  SIN*/
          SIU.PCR[107].R = 0x0a07;         /* assign port PG[11] pad to Alt Func 2 input  CS0 */
          SIU.PCR[108].R = 0x0a04;         /* assign port PG[12] pad to Alt Func 2 output SOUT*/
          SIU.PCR[109].R = 0x0a04;         /* assign port PG[13] pad to Alt Func 2 output SCK*/
         }
         else
         {
          SIU.PCR[106].R = 0x0104;         /* assign port PG[10] pad to Alt Func 2  input SIN*/
          SIU.PCR[107].R = 0x0907;         /* assign port PG[11] pad to Alt Func 2 input CS0 */
          SIU.PCR[108].R = 0x0a04;         /* assign port PG[12] pad to Alt Func 2 output SOUT*/
          SIU.PCR[109].R = 0x0904;         /* assign port PG[13] pad to Alt Func 2 input SCK*/
         }
     }

#endif
#endif
}

/*******************************************************************************
 * @brief   Deactivates the SPI peripheral and stop.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 *
 * @api
 *******************************************************************************/
void SPI_LLD_DeInit(const SPIDriver *spip)
{
  /* Releases the allocated EDMA channels.*/

  if (&SPID1 == spip)
  {
    spi_lld_resetdma(spi_dspi0_tx1_dma_config, /*PRQA S 3473*/
                     spi_dspi0_tx2_dma_config,
                     spi_dspi0_rx_dma_config)
  }

  if (&SPID2 == spip)
  {
    spi_lld_resetdma(spi_dspi1_tx1_dma_config, /*PRQA S 3473*/
                     spi_dspi1_tx2_dma_config,
                     spi_dspi1_rx_dma_config)
  }
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144)
  if (&SPID3 == spip)
  {
    spi_lld_resetdma(spi_dspi2_tx1_dma_config, /*PRQA S 3473*/
                     spi_dspi2_tx2_dma_config,
                     spi_dspi2_rx_dma_config)
  }
#if defined CCFC2011BC_40L5_LQFP144
  if (&SPID4 == spip)
  {
    spi_lld_resetdma(spi_dspi3_tx1_dma_config, /*PRQA S 3473*/
                     spi_dspi3_tx2_dma_config,
                     spi_dspi3_rx_dma_config)
  }

  if (&SPID5 == spip)
  {
    spi_lld_resetdma(spi_dspi4_tx1_dma_config, /*PRQA S 3473*/
                     spi_dspi4_tx2_dma_config,
                     spi_dspi4_rx_dma_config)
  }

#endif
#endif
  /* Resets the peripheral.*/
  spip->dspi->CTAR[0].R  = 0u;
  spip->dspi->RSER.R     = 0u;
  spip->dspi->SR.R       = 0xFFFFFFFFU;
  spip->dspi->MCR.R     |= MCR_HALT |
                           MCR_CLR_TXF | MCR_CLR_RXF;
  spip->dspi->MCR.B.MDIS = 1u;
}
/*******************************************************************************
 * @brief   Install INT functions for  the SPI peripheral.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 *
 * @api
 *******************************************************************************/

void SPI_LLD_Install_INT(SPIDriver *spip)/*PRQA S 1505*/
{
    if (spip->config->WhichSpiController == DSPI0)/*PRQA S 1505*/
    {
        if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_NONE)
        {
          INTC_InstallINTCInterruptHandler(DSPI0_RFDF_HANDLER, DSPI0_RFDF_NUMBER, SPI_DSPI0_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI0_TFFF_HANDLER, DSPI0_TFFF_NUMBER, SPI_DSPI0_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI0_EOQF_HANDLER, DSPI0_EOQF_NUMBER, SPI_DSPI0_IRQ_PRIO);
        }
        else
        {
          INTC_InstallINTCInterruptHandler(DSPI0_TFFF_HANDLER, DSPI0_TFFF_NUMBER, SPI_DSPI0_IRQ_PRIO);
          spi_lld_setdma((spip), (spi_dspi0_tx1_dma_config), (spi_dspi0_tx2_dma_config), (spi_dspi0_rx_dma_config))
          if ((uint8_t)spip->config->dmaType == (uint8_t)SPI_DMA_RX_AND_TX)
          {
              spip->dspi->RSER.R = RSER_TFFF_RE | RSER_TFFF_DIRS | RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
          else
          {
              spip->dspi->RSER.R = RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
        }
    }

    if (spip->config->WhichSpiController == DSPI1)
    {
        if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_NONE)
        {
          INTC_InstallINTCInterruptHandler(DSPI1_RFDF_HANDLER, DSPI1_RFDF_NUMBER, SPI_DSPI1_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI1_TFFF_HANDLER, DSPI1_TFFF_NUMBER, SPI_DSPI1_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI1_EOQF_HANDLER, DSPI1_EOQF_NUMBER, SPI_DSPI1_IRQ_PRIO);
        }
        else
        {
          INTC_InstallINTCInterruptHandler(DSPI1_TFFF_HANDLER, DSPI1_TFFF_NUMBER, SPI_DSPI1_IRQ_PRIO);
          spi_lld_setdma((spip), (spi_dspi1_tx1_dma_config), (spi_dspi1_tx2_dma_config), (spi_dspi1_rx_dma_config))
          if ((uint8_t)spip->config->dmaType == (uint8_t)SPI_DMA_RX_AND_TX)
          {
              spip->dspi->RSER.R = RSER_TFFF_RE | RSER_TFFF_DIRS | RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
          else
          {
              spip->dspi->RSER.R = RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
        }
    }

#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144)
    if (spip->config->WhichSpiController == DSPI2)
    {
        if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_NONE)
        {
          INTC_InstallINTCInterruptHandler(DSPI2_RFDF_HANDLER, DSPI2_RFDF_NUMBER, SPI_DSPI2_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI2_TFFF_HANDLER, DSPI2_TFFF_NUMBER, SPI_DSPI2_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI2_EOQF_HANDLER, DSPI2_EOQF_NUMBER, SPI_DSPI2_IRQ_PRIO);
        }
        else
        {
          INTC_InstallINTCInterruptHandler(DSPI2_TFFF_HANDLER, DSPI2_TFFF_NUMBER, SPI_DSPI2_IRQ_PRIO);
          spi_lld_setdma((spip), (spi_dspi2_tx1_dma_config), (spi_dspi2_tx2_dma_config), (spi_dspi2_rx_dma_config))
          if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_RX_AND_TX)
          {
              spip->dspi->RSER.R = RSER_TFFF_RE | RSER_TFFF_DIRS | RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
          else
          {
              spip->dspi->RSER.R = RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
        }
    }
#if defined CCFC2011BC_40L5_LQFP144
    if (spip->config->WhichSpiController == DSPI3)
    {
        if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_NONE)
        {
          INTC_InstallINTCInterruptHandler(DSPI3_RFDF_HANDLER, DSPI3_RFDF_NUMBER, SPI_DSPI3_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI3_TFFF_HANDLER, DSPI3_TFFF_NUMBER, SPI_DSPI3_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI3_EOQF_HANDLER, DSPI3_EOQF_NUMBER, SPI_DSPI3_IRQ_PRIO);
        }
        else
        {
          INTC_InstallINTCInterruptHandler(DSPI3_TFFF_HANDLER, DSPI3_TFFF_NUMBER, SPI_DSPI3_IRQ_PRIO);
          spi_lld_setdma((spip), (spi_dspi3_tx1_dma_config), (spi_dspi3_tx2_dma_config), (spi_dspi3_rx_dma_config))
          if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_RX_AND_TX)
          {
              spip->dspi->RSER.R = RSER_TFFF_RE | RSER_TFFF_DIRS | RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
          else
          {
              spip->dspi->RSER.R = RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
        }
    }

    if (spip->config->WhichSpiController == DSPI4)
    {
        if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_NONE)
        {
          INTC_InstallINTCInterruptHandler(DSPI4_RFDF_HANDLER, DSPI4_RFDF_NUMBER, SPI_DSPI4_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI4_TFFF_HANDLER, DSPI4_TFFF_NUMBER, SPI_DSPI4_IRQ_PRIO);
          INTC_InstallINTCInterruptHandler(DSPI4_EOQF_HANDLER, DSPI4_EOQF_NUMBER, SPI_DSPI4_IRQ_PRIO);
        }
        else
        {
          INTC_InstallINTCInterruptHandler(DSPI4_TFFF_HANDLER, DSPI4_TFFF_NUMBER, SPI_DSPI4_IRQ_PRIO);
          spi_lld_setdma((spip), (spi_dspi4_tx1_dma_config), (spi_dspi4_tx2_dma_config), (spi_dspi4_rx_dma_config))
          if ((uint8_t)(spip->config->dmaType) == (uint8_t)SPI_DMA_RX_AND_TX)
          {
              spip->dspi->RSER.R = RSER_TFFF_RE | RSER_TFFF_DIRS | RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
          else
          {
              spip->dspi->RSER.R = RSER_RFDF_RE | RSER_RFDF_DIRS;
          }
        }
    }

#endif
#endif
}
/****************************************************************
 * @brief   Low level SPI driver initialization.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] config    pointer to the @p SPIConfig object
 *
 * @init
 ***************************************************************/
void SPI_LLD_Init(SPIDriver *spip, const spi_config_t *config, spi_functional_mode_t spi_mode)
{
      uint32_t ret = 0u;
      spip->config = config;
      /*configure DSPIx pins as sck, cs_0, mosi, miso */
      SPI_LLD_Gpio_Init((uint8_t)config->WhichSpiController, (uint8_t)spi_mode);

      /* Set SPI mode (Master/Slave).*/
      if (spi_mode == SPI_MASTER)
      {
        spip->dspi->MCR.B.MSTR = 1u;
      }
      else
      {
        spip->dspi->MCR.B.MSTR = 0u;
      }

      spip->dspi->MCR.B.CONT_SCKE = spip->config->isClkContinuous;
      spip->dspi->MCR.R |= (((uint32_t)spip->config->pcsPolarity << spip->config->whichPCS) << 16U);

      /*clear TX and RX FIFO*/
      spip->dspi->MCR.B.CLR_RXF = 1u;
      spip->dspi->MCR.B.CLR_TXF = 1;

      /*when DSPI configured as an SPI bus Slave, the DSPIX_CATR0 is used.so default to use CATR0 for Master and slave*/

      spip->dspi->CTAR[0].B.LSBFE  = spip->config->lsbFirst;
      spip->dspi->CTAR[0].B.CPHA   = (uint8_t)(spip->config->clkPhase);
      spip->dspi->CTAR[0].B.CPOL   = (uint8_t)(spip->config->clkPolarity);

      /*baudrate only can be set in Master mode*/
      ret = SPI_LLD_SetbaudRate(spip, spip->config->bitsPerSec, (64000000u/(1u + ((uint32_t)CGM.SC_DC1.B.DIV1)))); /*PRQA S 1891*/
      if (ret == 0u)
      {
          spip->dspi->CTAR[0].B.BR  = CTAR_BR_DIV2;

          PSPRINTF("\n using default baudrate :F_systemclock/4!\n");
      }

      spip->dspi->CTAR[0].B.FMSZ = (spip->config->bitcount - 1u);
      spip->dspi->CTAR[0].B.CSSCK  = 0x03u;
      spip->dspi->SR.R = 0xFFFFFFFFU;

      if ((uint8_t)(config->dmaType) != (uint8_t)SPI_DMA_NONE)
      {
        /*EDMA Init */
        EdmaInit();
      }
      if ((config->transferType) == SPI_USING_INTERRUPTS)
      {
          SPI_LLD_Install_INT(spip);
      }

      /*Module Enable */
      spip->dspi->MCR.B.MDIS = 0u;
}

void SPI_LLD_SetCATR0_NoFmsz(const SPIDriver *spip, uint32_t catr0_reg)
{
    uint8_t fmsz = spip->dspi->CTAR[0].B.FMSZ;
    spip->dspi->CTAR[0].R = 0u;
    spip->dspi->CTAR[0].R = catr0_reg | ((uint32_t)fmsz << 27U) ;
}

/*******************************************************************************
 * @brief      SPI_LLD_SetbaudRate
 * @param[in]  const SPIDriver *spip, uint32_t bitsPerSec, uint32_t sourceClockInHz
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
uint32_t SPI_LLD_SetbaudRate(const SPIDriver *spip, uint32_t bitsPerSec, uint32_t sourceClockInHz)/*PRQA S 1505*/
{
    uint32_t bestFreq = 0xFFFFFFFFU;
    uint32_t bestScaler = 0U;
    uint32_t bestPrescaler = 0U;
    uint32_t freq1 = 0U;
    uint32_t freq2 = 0U;
    uint8_t scaler = 0U;
    uint8_t prescaler = 0U;
    uint32_t low, high;
    uint32_t tempBestFreq = 0U;
    uint32_t flag = 0U;
    const uint32_t s_PBR_baudratePrescaler[] = { 2, 3, 5, 7};
    const uint32_t s_BR_baudratePrescaler[] = { 2, 4, 6, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};

    for (scaler = 0U; scaler < 4U; scaler++)
    {
        low = 0U;
        high = 15U;

        /* Implement golden section search algorithm */
        do
        {
            prescaler = (uint8_t)((low + high) / 2U);
            freq1 = sourceClockInHz / (s_BR_baudratePrescaler[prescaler] * (s_PBR_baudratePrescaler[scaler]));

            if (abs_dif (bitsPerSec, bestFreq) > abs_dif (bitsPerSec, freq1))
            {
                bestFreq = freq1;
            }
            if (freq1 < bitsPerSec)
            {
                high = prescaler;
            }
            else
            {
                low = prescaler;
            }
        }
        while ((high - low) > 1U);

        /* Evaluate last 2 scaler values */
        freq1 = sourceClockInHz / (s_BR_baudratePrescaler[low] * (s_PBR_baudratePrescaler[scaler]));
        freq2 = sourceClockInHz / (s_BR_baudratePrescaler[high] * (s_PBR_baudratePrescaler[scaler]));

        if (abs_dif (bitsPerSec, freq1) > abs_dif (bitsPerSec, freq2))
        {
            tempBestFreq = freq2;
            bestPrescaler = high;
        }
        else
        {
            tempBestFreq = freq1;
            bestPrescaler = low;
        }

        if (abs_dif (bitsPerSec, bestFreq) >= abs_dif (bitsPerSec, tempBestFreq))
        {
            bestFreq = tempBestFreq;
            bestScaler = scaler;
            bestPrescaler = bestPrescaler;
        }

        /* If current frequency is equal to target frequency  stop the search */
        if (bestFreq == bitsPerSec)
        {
            flag = 1u;
            break;
        }
    }
    /* Write the best baud rate scalar and prescaler to the CATR0.*/
    if (flag == TRUE)
    {
        spip->dspi->CTAR[0].B.PBR = bestScaler;
        spip->dspi->CTAR[0].B.BR = bestPrescaler;
    }

    /* return the flag of calculating baud rate successfully*/
    return flag;
}
/*******************************************************************************
 * @brief   Ignores data on the SPI bus.
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be ignored
 *
 * @notapi
 *******************************************************************************/
static void SPI_LLD_Ignore(SPIDriver *spip, uint32_t n)/*PRQA S 3219*/
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);
    /* Setting up the DMA channels.*/
    Spi_Start_Rx_Ignore(spip, n);
    Spi_Start_Tx_Ignore(spip, n);
}

/*******************************************************************************
 * @brief   Exchanges data on the SPI bus.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[in] txbuf     the pointer to the transmit buffer
 * @param[out] rxbuf    the pointer to the receive buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Exchange(SPIDriver *spip, uint32_t n, uint8_t *txbuf, uint8_t *rxbuf) /*PRQA S 3673*/
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Rx8(spip, n, rxbuf);
        Spi_Start_Tx8(spip, n, txbuf);
    }
    else
    {
        Spi_Start_Rx16(spip, n, (uint16_t *)rxbuf); /*PRQA S 0310, 3305*/
        Spi_Start_Tx16(spip, n, (uint16_t *)txbuf); /*PRQA S 0310, 3305*/
    }
}

/*******************************************************************************
 * @brief   Exchanges data on the SPI bus, send and receive with dma.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[in] txbuf     the pointer to the transmit buffer
 * @param[out] rxbuf    the pointer to the receive buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Exchange_DMA(SPIDriver *spip, uint32_t n, uint8_t *txbuf, uint8_t *rxbuf) /*PRQA S 3673*/
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Rx8_dma(spip, n, rxbuf);
        Spi_Start_Tx8_dma(spip, n, txbuf);
    }
    else
    {
        Spi_Start_Rx16_dma(spip, n, (uint16_t *)rxbuf); /*PRQA S 0310, 3305*/
        Spi_Start_Tx16_dma(spip, n, (uint16_t *)txbuf); /*PRQA S 0310, 3305*/
    }
}

/*******************************************************************************
 * @brief   Exchanges data on the SPI bus , only receive data with dma.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to be exchanged
 * @param[in] txbuf     the pointer to the transmit buffer
 * @param[out] rxbuf    the pointer to the receive buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Exchange_DMA_Rx(SPIDriver *spip, uint32_t n, uint8_t *txbuf, uint8_t *rxbuf)/*PRQA S 3673*/
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Rx8_dma(spip, n, rxbuf);
        Spi_Start_Tx8(spip, n, txbuf);
    }
    else
    {
        Spi_Start_Rx16_dma(spip, n, (uint16_t*)rxbuf); /*PRQA S 0310, 3305*/
        Spi_Start_Tx16(spip, n, (uint16_t*)txbuf); /*PRQA S 0310, 3305*/
    }
}
/*******************************************************************************
 * @brief   Sends data over the SPI bus.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to send
 * @param[in] txbuf     the pointer to the transmit buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Send(SPIDriver *spip, uint32_t n,  uint8_t *txbuf) /*PRQA S 3673*/
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* Only for slave transmit */
    if (spip->dspi->MCR.B.MSTR == 0UL)
    {
        Spi_Start_Rx_Ignore(spip, n);
    }
    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Tx8(spip, n, txbuf);
    }
    else
    {
        Spi_Start_Tx16(spip, n, (uint16_t *)txbuf); /*PRQA S 0310, 3305*/
    }
}

/*******************************************************************************
 * @brief   Sends data over the SPI bus using dma.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to send
 * @param[in] txbuf     the pointer to the transmit buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Send_DMA(SPIDriver *spip, uint32_t n,  uint8_t *txbuf) /*PRQA S 3673*/
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* Setting up the RX DMA channel.*/
    Spi_Start_Rx_Ignore_dma(spip, n);

    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Tx8_dma(spip, n, txbuf);
    }
    else
    {
        Spi_Start_Tx16_dma(spip, n, (uint16_t *)txbuf); /*PRQA S 0310, 3305*/
    }
}
/*******************************************************************************
 * @brief   SPI Master Device Receives data from the SPI bus.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to receive
 * @param[out] rxbuf    the pointer to the receive buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Master_Receive(SPIDriver *spip, uint32_t n, uint8_t *rxbuf)
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Rx8(spip, n, rxbuf);
    }
    else
    {
        Spi_Start_Rx16(spip, n, (uint16_t *)rxbuf); /*PRQA S 0310, 3305*/
    }
    /* Only for master receive */
    if (spip->dspi->MCR.B.MSTR == 1UL)
    {
    /* Clock - in the data */
        Spi_Start_Tx_Ignore(spip, n);
    }
}
/*******************************************************************************
 * @brief   SPI Slave Device Receives data from the SPI bus.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to receive
 * @param[out] rxbuf    the pointer to the receive buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Slave_Receive(SPIDriver *spip, uint32_t n, uint8_t *rxbuf)
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Rx8(spip, n, rxbuf);
    }
    else
    {
        Spi_Start_Rx16(spip, n, (uint16_t *)rxbuf); /*PRQA S 0310, 3305*/
    }
}
/*******************************************************************************
 * @brief   Receives data from the SPI bus using DMA.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to receive
 * @param[out] rxbuf    the pointer to the receive buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Receive_DMA(SPIDriver *spip, uint32_t n, uint8_t *rxbuf)/*PRQA S 3673*/
{
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);

    SPI_TXRX_IN_PROGRESS(spip);

    /* DMAs require a different setup depending on the frame size.*/
    if (spip->dspi->CTAR[0].B.FMSZ < 8U)
    {
        Spi_Start_Rx8_dma(spip, n, rxbuf);
    }
    else
    {
        Spi_Start_Rx16_dma(spip, n, (uint16_t *)rxbuf); /*PRQA S 0310, 3305*/
    }

    Spi_Start_Tx_Ignore_dma(spip, n);
}
/*******************************************************************************
 * @brief   Exchange a frame from the SPI bus using Poll.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] frame     frame to send
 * @param[in] last_frame   is last frame or not
 * @param[out] none  
 * @return  the received frame   
 * @notapi
 *******************************************************************************/
uint16_t SPI_LLD_Polled_Exchange_Frame(const SPIDriver *spip, uint16_t frame, uint8_t last_frame)/*PRQA S 1505*/
{
    uint32_t popr;
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));

    while (spip->dspi->SR.B.TFFF == 0u)/*Wait TX FIFO is not full*/
    {}
    /* Data exchange.*/ /*if reduce the interval between frames, can shield this line of code*/
    if (last_frame == 1u)
    {
        spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd |(uint32_t)frame) & ~PUSHR_CONT;
    }
    else
    {
        spip->dspi->PUSHR.R = (cmd |(uint32_t)frame);
    }
    delay(0x5);

    while (spip->dspi->SR.B.RFDF == 0u)
    {}
    popr = spip->dspi->POPR.R;
    spip->dspi->SR.B.RFDF = 1u;

    return (uint16_t)popr;
}
/*******************************************************************************
 * @brief   Exchange data from the SPI bus using Poll.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to receive
 * @param[in] txbuf     the pointer to the transmit buffer
 * @param[out] rxbuf    the pointer to the receive buffer  
 * @notapi
 *******************************************************************************/
void SPI_LLD_Polled_Exchange(SPIDriver *spip, uint32_t n, uint8_t *txbuf, uint8_t *rxbuf)/*PRQA S 3673*/
{
    uint32_t len = n;
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);
    
    SPI_TXRX_IN_PROGRESS(spip);
    
    if (spip->dspi->CTAR[0].B.FMSZ < 8u)
    {
        /* Transmit Data .*/
        while (len != 1u)
        {
          *((uint8_t*)rxbuf)++ = SPI_LLD_Polled_Exchange_Frame(spip, *((uint8_t*)txbuf)++, 0); /*PRQA S 0447, 2982 */
          len--;
        }
        *((uint8_t*)rxbuf)++ = SPI_LLD_Polled_Exchange_Frame(spip, *((uint8_t*)txbuf)++, 1); /*PRQA S 0447 */
    }
    else
    {
        /* Transmit Data .*/
        while (len != 1u)
        {
          *((uint16_t*)rxbuf)++ = SPI_LLD_Polled_Exchange_Frame(spip, *((uint16_t*)txbuf)++, 0); /*PRQA S 0310, 0447, 3305 */
          len--;
        }
        *((uint16_t*)rxbuf)++ = SPI_LLD_Polled_Exchange_Frame(spip, *((uint16_t*)txbuf)++, 1); /*PRQA S 0310, 0447, 3305 */
    }
    /* Stopping transfer.*/
    Spi_Dspi_Stop(spip);
    SPI_TXRX_DONE(spip);
}
/*******************************************************************************
 * @brief   Send a frame to SPI bus using Poll.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] frame     frame to send
 * @param[in] last_frame   is last frame or not
 * @notapi
 *******************************************************************************/
void SPI_LLD_Polled_Send_Frame(const SPIDriver *spip, uint16_t frame, uint8_t last_frame)/*PRQA S 1505*/
{
    uint32_t cmd = (((((uint32_t)(spip->config->continuousPCS)) << 31) &
     (~(((uint32_t)(spip->config->continuousPCS)) << 27))) |
    (((uint32_t)(((uint32_t)1) << ((uint32_t)(spip->config->whichPCS)))) << 16));

    while (spip->dspi->SR.B.TFFF == 0u) //  Wait TX FIFO is not full
    {}

    /* Transmit Data .*/
    if (last_frame == 1u)
    {
        spip->dspi->PUSHR.R = (PUSHR_EOQ | cmd |(uint32_t)frame) & ~PUSHR_CONT;
    }
    else
    {
        spip->dspi->PUSHR.R = (cmd |(uint32_t)frame);
    }
  }
/*******************************************************************************
 * @brief   Send a frame to SPI bus using Poll.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to receive
 * @param[in] txbuf     the pointer to the transmit buffer
 * @notapi
 *******************************************************************************/
void SPI_LLD_Polled_Send(SPIDriver *spip, uint32_t n, uint8_t *txbuf)/*PRQA S 3673*/
{
    uint32_t len = n;
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);
    SPI_TXRX_IN_PROGRESS(spip);

    if (spip->dspi->CTAR[0].B.FMSZ < 8u)
    {
        /* Transmit Data .*/
        while (len != 1u)
        {
          SPI_LLD_Polled_Send_Frame(spip, *((uint8_t*)txbuf)++, 0); /*PRQA S 0447 */
          len--;
          /* waiting for transfer finish.*/
          while (spip->dspi->SR.B.TCF != 1u)
          {}
          spip->dspi->SR.B.TCF = 1u;
          spip->dspi->MCR.B.CLR_TXF = 1u;
        }

        SPI_LLD_Polled_Send_Frame(spip, *((uint8_t*)txbuf)++, 1u); /*PRQA S 0447 */
    }
    else
    {
        /* Transmit Data .*/
        while (len != 1U)
        {
          SPI_LLD_Polled_Send_Frame(spip, *((uint16_t*)txbuf)++, 0u); /*PRQA S 0310, 0447, 3305 */
          len--;
          /* waiting for transfer finish.*/
          while (spip->dspi->SR.B.TCF != 1u)
          {}
          spip->dspi->SR.B.TCF = 1u;
          spip->dspi->MCR.B.CLR_TXF = 1u;
        }
        SPI_LLD_Polled_Send_Frame(spip, *((uint16_t*)txbuf)++, 1u); /*PRQA S 0310, 0447, 3305 */
    }

    /* Stopping transfer.*/
    Spi_Dspi_Stop(spip);
    SPI_TXRX_DONE(spip);
}
/*******************************************************************************
 * @brief   Exchange data from the SPI bus using Poll.
 * @note    The buffers are organized as uint8_t arrays for data sizes below or
 *          equal to 8 bits else it is organized as uint16_t arrays.
 *
 * @param[in] spip      pointer to the @p SPIDriver object
 * @param[in] n         number of words to receive
 * @param[in] txbuf     the pointer to the transmit buffer
 * @param[out] rxbuf    the pointer to the receive buffer  
 * @notapi
 *******************************************************************************/
void SPI_LLD_Slave_Polled_Receive(SPIDriver *spip, uint32_t n, uint8_t *rxbuf)
{
    uint32_t len = n;
    /* Starting transfer.*/
    Spi_Dspi_Start(spip);
    SPI_TXRX_IN_PROGRESS(spip); 

    if (spip->dspi->CTAR[0].B.FMSZ < 8u)
    {
        while (len != 0U)
        {
          while (spip->dspi->SR.B.RFDF == 0u)
          {}
          (*((uint8_t*)rxbuf)++) = (uint8_t)spip->dspi->POPR.R;  /*PRQA S 0447 */
          spip->dspi->SR.B.RFDF = 1u;
          len--;
        }
    }
    else
    {
        while (len != 0U)
        {
          while (spip->dspi->SR.B.RFDF == 0u)
          {}
          (*((uint16_t*)rxbuf)++) = (uint16_t)spip->dspi->POPR.R;  /*PRQA S 0310, 0447, 3305 */
          spip->dspi->SR.B.RFDF = 1u;
          len--;
        }
    }
    /* Stopping transfer.*/
    Spi_Dspi_Stop(spip);
    SPI_TXRX_DONE(spip);
}
